package com.hjy.core.transport.netty.client;

import com.hjy.common.entity.RpcRequest;
import com.hjy.common.entity.RpcResponse;
import com.hjy.core.codec.CommonCodec;
import com.hjy.core.nacos.NacosServiceRegistry;
import com.hjy.core.nacos.ServiceRegistry;
import com.hjy.core.serializer.CommonSerializer;
import com.hjy.core.serializer.JsonSerializer;
import com.hjy.core.serializer.KryoSerializer;
import com.hjy.core.transport.RpcClient;
import com.hjy.core.transport.netty.handler.NettyClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.AttributeKey;

import java.net.InetSocketAddress;

/**
 * netty 客户端
 */
public class NettyClient implements RpcClient {
    /**
     * netty 的启动器
     */
    private static Bootstrap bootstrap;

    private ServiceRegistry serviceRegistry;

    private static CommonSerializer serializer;

    public NettyClient() {
        this.serviceRegistry = new NacosServiceRegistry();
        serializer = new KryoSerializer();
    }

    public NettyClient(CommonSerializer serializer2) {
        this.serviceRegistry = new NacosServiceRegistry();
        serializer = serializer2;
    }

    static {
        bootstrap = new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new LengthFieldBasedFrameDecoder(1 << 20, 12, 4, 0, 0));
                        pipeline.addLast(new CommonCodec(serializer));
                        pipeline.addLast(new NettyClientHandler());
                    }
                });
    }


    @Override
    public Object sendRequest(RpcRequest rpcRequest) {
        try {
            InetSocketAddress inetSocketAddress = serviceRegistry.lookupService(rpcRequest.getInterfaceName());
            ChannelFuture channelFuture = bootstrap.connect(inetSocketAddress).sync();
            System.out.println("客户端连接到服务器: " + inetSocketAddress.getHostString() + " " + inetSocketAddress.getPort());
            Channel channel = channelFuture.channel();
            if (channel != null) {
                // 发送信息
                channel.writeAndFlush(rpcRequest);
            }
            if (channel != null) {
                // 关闭 channel
                channel.closeFuture().sync();
            }
            // 获取值
            AttributeKey<RpcResponse> key = AttributeKey.valueOf("rpcResponse");
            RpcResponse rpcResponse = channel.attr(key).get();
            return rpcResponse;
        } catch (InterruptedException e) {
            System.err.println("发送信息过程中有错误!!!");
        }
        return null;
    }
}
